#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author  : Lee
# @File    : matplotlib_view.py
# @Time    : 2023/2/24 11:14
import matplotlib
import numpy as np
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QWidget

matplotlib.use("Qt5Agg")  # 声明使用pyqt5
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg  # pyqt5的画布
from matplotlib.backends.backend_qt5 import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure


class MplWidget(QWidget):
    def __init__(self, parent=None):
        """
        :param parent:
        """
        QWidget.__init__(self, parent)
        self.qCanvas = MatplotlibFigure(parent)
        self.mpl_toolbar = NavigationToolbar(self.qCanvas, self)  # 创建工具条
        # 创建布局，把画布类组件对象和工具条对象添加到QWidget控件中
        self.vbl = QtWidgets.QVBoxLayout()
        self.vbl.addWidget(self.mpl_toolbar)
        self.vbl.addWidget(self.qCanvas)
        self.setLayout(self.vbl)


class MatplotlibFigure(FigureCanvasQTAgg):
    """
    创建一个画布类，并把画布放到FigureCanvasQTAgg
    """

    def __init__(self, parent=None, width=5, height=4, dpi=80):
        """
        :param parent:
        :param width:
        :param height:
        :param dpi:
        """
        figure = Figure(figsize=(width, height), dpi=dpi)
        super(MatplotlibFigure, self).__init__(figure)  # 在父类中激活self.fig
        self.setParent(parent)
        self.ax = figure.add_subplot()
        self.ax.patch.set_alpha(0.5)  # 设置ax区域背景颜色透明度
        FigureCanvasQTAgg.setSizePolicy(self, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        # 用于告知包含该widget的layout：该widget的size hint已发生变化，layout会自动进行调整。
        FigureCanvasQTAgg.updateGeometry(self)

        # 静态测试中心点
        self.center_point, = self.ax.plot([], [], 'gX')

        # 保存A、B点索引及坐标信息
        self.point_a_b_map = dict()
        # 动态测试A、B点
        self.point_a_b, = self.ax.plot([], [], 'r*', linestyle='-.')

        # 动态轨迹线
        self.draw_line, = self.ax.plot([], [], linestyle='--')
        # 动态轨迹点
        self.draw_point, = self.ax.plot([], [], 'bo', picker=5, markersize=3)  # 使用散点图
        self.ax.grid()

        # 绘制绕圈行驶轨迹
        self.draw_circle, = self.ax.plot([], [], linestyle='-.')

        self.parent_obj = parent
        # # 添加matplotlib监听事件
        figure.canvas.mpl_connect('pick_event', self.on_pick_point)

# 在散点图上选取A、B点
    def on_pick_point(self, event):
        # 获取点的坐标及索引，取到多个点，默认取最后一个
        idx = event.ind[-1]
        self.parent_obj.get_clicked_index(event.ind[-1])
#         # 只有动态测试才开发此功能
#         if self.parent_obj.test_type_box.currentText() == "动态测试":
#             # 获取被识取到的数据元素
#             line = event.artist
#             # 获取点的坐标及索引，取到多个点，默认取最后一个
#             idx = event.ind[-1]
#             point_x, point_y = line.get_data()
#             if "point_a" not in self.point_a_b_map.keys():
#                 self.point_a_b_map["point_a"] = {
#                     "index": idx,
#                     "point": [point_x[idx], point_y[idx]]
#                 }
#             elif "point_b" not in self.point_a_b_map.keys():
#                 self.point_a_b_map["point_b"] = {
#                     "index": idx,
#                     "point": [point_x[idx], point_y[idx]]
#                 }
#             if len(self.point_a_b_map.keys()) == 2:
#                 dis = calc_distance(*self.point_a_b_map["point_a"]["point"], *self.point_a_b_map["point_b"]["point"])
#                 print("AB点之间的距离为：{} 米".format(dis))
#             self.update_a_b_line()

    # 更新图表
    def refresh(self):
        self.ax.relim()
        self.ax.autoscale()  # fix bug, 缩放或移动后重新绘制新曲线时视图区域不改
        # https://github.com/ifarup/ciefunctions/issues/124
        # https://github.com/ifarup/ciefunctions/commit/01526210c35ad81e78db9b03169708553c7c660e
        # self.toolbar.update()
        self.draw()
        self.flush_events()

    # 更新散点图
    def update_data(self, point_list, ab_line_points=list()):
        # 清空数据后再进行绘制
        self.clear_matplotlib_data()
        point_list = np.array(point_list)
        x = point_list[:, 0]
        y = point_list[:, 1]
        if ab_line_points:
            self.point_a_b.set_xdata(ab_line_points[0])
            self.point_a_b.set_ydata(ab_line_points[1])
        # # # 若为动态测试，在绘制运行轨迹线
        # self.draw_line.set_xdata(x)
        # self.draw_line.set_ydata(y)
        self.draw_point.set_xdata(x)
        self.draw_point.set_ydata(y)
        if hasattr(self, 'fill'):
            self.ax.collections.remove(self.fill)
        self.refresh()

    # 更新静态中心坐标点
    def update_data_center(self, center):
        # 清空数据后再进行绘制
        self.clear_line()
        self.clear_matplotlib_data()
        self.center_point.set_xdata([center[0]])
        self.center_point.set_ydata([center[1]])
        self.refresh()

    # 更新圆形轨迹
    def update_circle(self, x, y):
        self.draw_circle.set_xdata(x)
        self.draw_circle.set_ydata(y)
        self.refresh()

    # 更新A、B点坐标及A、B线
    def update_a_b_line(self, ab_points):
        # x_data, y_data = [], []
        # for key in self.point_a_b_map.keys():
        #     point = self.point_a_b_map[key]["point"]
        #     x_data.append(point[0])
        #     y_data.append(point[1])
        #     eval("self.parent_obj.{}_x_text.setText(str(point[0])[:16])".format(key))
        #     eval("self.parent_obj.{}_y_text.setText(str(point[1])[:16])".format(key))
        # 清空数据后再进行绘制
        self.clear_matplotlib_data()
        self.point_a_b.set_xdata(ab_points[0])
        self.point_a_b.set_ydata(ab_points[1])
        self.refresh()

    # 清空 matplotlib 数据
    def clear_matplotlib_data(self):
        # 清空A、B线
        self.point_a_b.set_xdata([])
        self.point_a_b.set_ydata([])

        # 清空中心点
        self.center_point.set_xdata([])
        self.center_point.set_ydata([])

        # 清空圆形轨迹
        self.draw_circle.set_xdata([])
        self.draw_circle.set_ydata([])

    # 清空轨迹线
    def clear_line(self):
        self.draw_line.set_xdata([])
        self.draw_line.set_ydata([])
